/***************************************************************************
 *   Copyright (C) 2009 by Marian Skvarek   *
 *   skvarek.marian@gmail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "CEasyScoreApp.h"
#include "CEasyScoreMainWindow.h"
#include "CDebug.h"
#include "CEasyScoreExporter.h"
#include "CMusicXmlExporter.h"
#include "CMusicXmlImporter.h"
#include "CTabExporter.h"
#include "CDialogSetup.h"
#include "CGraphicsView.h"
#include "CScoreView.h"
#include "CPart.h"
#include "CBar.h"
#include "CBarView.h"
#include "CGlobals.h"

#include <QtGlobal>
#include <QPixmap>
#include <QPainter>
#include <QPrinter>
#include <QPrintDialog>

using namespace easyscore::utils;
using namespace easyscore::components;
using namespace easyscore::components::io;
using namespace easyscore::gui;
using namespace easyscore::globals;

namespace easyscore
{

	CEasyScoreApp::CEasyScoreApp()
	{
                mScore = 0;
                mCurrentFile = "";
		mCurrentNoteValue = NOTE_VALUE_QUARTER;
		mGUI = 0;
	}

	void CEasyScoreApp::initialize()
	{
		CDebug::getInstance()->writeDebugInfo(qVersion());
	}
	
	void CEasyScoreApp::clear()
	{
		
	}

	CEasyScoreApp::~CEasyScoreApp()
	{
		clear();
		
		destroyGUI();
	}

        bool CEasyScoreApp::newScore()
        {
            CScore *newScore = createScore();
            CDialogSetup setup;
            if ( setup.exec() == QDialog::Accepted )
            {
                    newScore->initialize ( setup.getSetupSettings() );
                    setScore(newScore);
                    return true;
            }
            else
            {
                    return false;
            }

        }

        bool CEasyScoreApp::save(QFile &file)
         {
            if(!mScore)
                return false;

             CEasyScoreExporter exporter;
             if( exporter.exportScore(mScore,file))
             {
                 setCurrentFile(file.fileName());
                 return true;
             }
             else
             {
                 return false;
             }
         }

        bool CEasyScoreApp::load(QFile &file)
         {
             CEasyScoreExporter importer;
             CScore *score = createScore();
             if(importer.importScore(score,file))
             {
                 setScore(score);
                 return true;
             }
             else
                 return false;
         }

        bool CEasyScoreApp::exportToPDF(QFile &file)
        {
            if(!mScore)
                return false;

            //TODO: odstran ramceky
//            foreach(CPart *part,mScore->getParts())
//            {
//                if(part-)
//            }

            QPrinter printer;
            printer.setOutputFileName(file.fileName());
            QPainter painter(&printer);

            int maxBarCount = 0;
            CBar *randomBar;
            QLinkedList<CTrack *> tracks = mScore->getTracks();
            foreach(CTrack * track, tracks)
            {
                if(track->getBars().count() > maxBarCount)
                {
                    maxBarCount = track->getBars().count();
                    randomBar = track->getBars().first();
                }
            }

            int barWidth = 10000;
            if(randomBar->hasView())
                barWidth = randomBar->getView()->rect().width();

            int barCount = 1;
            int curr = 0;
            while( curr < maxBarCount)
            {
                foreach(CTrack *track, tracks)
                {
                    track->setActiveBars(curr,barCount,true);
                    track->updateView();
                }

                mScore->getView()->render(&painter);

                curr += barCount;

                if(curr < maxBarCount)
                    printer.newPage();
            }

            painter.end();



            foreach(CTrack *track,tracks)
            {
                track->setActiveBars(0,10000,true);
                track->updateView();
            }


            return true;
        }

        bool CEasyScoreApp::exportMIDI(QFile &file)
        {
            return true;
        }

        bool CEasyScoreApp::exportImage(QString dir)
        {
            if(!mScore)
                return false;

            const int w = 2480;
            const int h = 3508;
            const int scoreHeight = mScore->getView()->width();
            const int scoreWidth = (scoreHeight * w ) / h;

            int maxBarCount = 0;
            CBar *randomBar;
            QLinkedList<CTrack *> tracks = mScore->getTracks();
            foreach(CTrack * track, tracks)
            {
                if(track->getBars().count() > maxBarCount)
                {
                    maxBarCount = track->getBars().count();
                    randomBar = track->getBars().first();
                }
            }

            int barWidth = 10000;
            if(randomBar->hasView())
                barWidth = randomBar->getView()->rect().width();

            int barCount = 1; //CUtils::max(1, (scoreWidth - CGlobals::getEmptyTrackWidth())/barWidth);
            int count = 0;
            int curr = 0;
            while( curr < maxBarCount)
            {
                foreach(CTrack *track, tracks)
                {
                    track->setActiveBars(curr,barCount,true);
                    track->updateView();
                }

                //mScore->getView()->setWidth(scoreWidth);

                QPixmap pixmap(w,h);
                pixmap.fill();
                QPainter painter(&pixmap);
                mScore->getView()->render(&painter,QRectF(),mScore->getView()->itemsBoundingRect());
                painter.end();

                QString fileName = dir + "/" + QString::number( count + 1) + ".png";
                QFile file(fileName);
                if(file.exists())
                    file.remove();


                pixmap.save(fileName);

                ++count;
                curr += barCount;
            }



            foreach(CTrack *track,tracks)
            {
                track->setActiveBars(0,10000,true);
                track->updateView();
            }

            //mScore->getView()->update();

            bool succ = true;
            return succ;
        }

        bool CEasyScoreApp::exportTab(QFile &file)
        {
            if(!mScore)
                return false;

            CTabExporter exp;
            return exp.exportTablature(mScore,file);
        }

        bool CEasyScoreApp::exportMusicXML(QFile &file)
        {
            if(!mScore)
                return false;

            CMusicXmlExporter exp;
            return exp.exportScore(mScore,file);
        }

        bool CEasyScoreApp::print()
        {
            if(!mScore)
                return false;

            QPrinter printer;
            if (QPrintDialog(&printer).exec() != QDialog::Accepted)
                return false;
            QPainter painter(&printer);

            int maxBarCount = 0;
            CBar *randomBar;
            QLinkedList<CTrack *> tracks = mScore->getTracks();
            foreach(CTrack * track, tracks)
            {
                if(track->getBars().count() > maxBarCount)
                {
                    maxBarCount = track->getBars().count();
                    randomBar = track->getBars().first();
                }
            }

            int barWidth = 10000;
            if(randomBar->hasView())
                barWidth = randomBar->getView()->rect().width();

            int barCount = 1;
            int curr = 0;
            while( curr < maxBarCount)
            {
                foreach(CTrack *track, tracks)
                {
                    track->setActiveBars(curr,barCount,true);
                    track->updateView();
                }

                mScore->getView()->render(&painter/*,QRectF(),mScore->getView()->itemsBoundingRect()*/);

                curr += barCount;

                if(curr < maxBarCount)
                    printer.newPage();
            }

            painter.end();



            foreach(CTrack *track,tracks)
            {
                track->setActiveBars(0,10000,true);
                track->updateView();
            }


            return true;
        }
	
        void CEasyScoreApp::addBar()
        {
            if(!mScore)
                return;

            foreach(CTrack *track, mScore->getTracks())
                track->addBar();
        }

	void CEasyScoreApp::createAndShowGUI()
	{
		mGUI = new CEasyScoreMainWindow(this);
		mGUI->initialize();
		mGUI->show();
	}
	
	void CEasyScoreApp::destroyGUI()
	{
		if(hasGUI())
		{
			delete mGUI;
			mGUI = 0;
		}
	}

//Protected methods
        void CEasyScoreApp::setScore(CScore *score)
        {
            if(mScore)
            {
                delete mScore;
            }

            mScore = score;
            mScore->setModified(false);
            if(!mScore->hasView())
                mScore->createView();

            if(mGUI)
            {
                mGUI->getScoreSceneView()->setScene(mScore->getView());
            }

        }

        CScore *CEasyScoreApp::createScore()
        {
            CScore *newScore = new CScore();
            newScore->setParentApp(this);

            return newScore;
        }


}
